//
// Created by lyx on 2020/8/2.
//

#include <Utils.h>
#include <iostream>
#include <vector>
using namespace std;
using namespace lyxutils::abbreviations;

template<typename T>
void displayVec(string head, const lyxutils::Vector3<T> &v,string tail="\n"){
    cout<<head;
    for(int i=0;i<3;++i)cout<<v[i]<<" ";
    cout<<",value type="<< typeid(decltype(v.x)).name();
    cout<<tail;
}

//template<typename T>
//class TD;

int main(int argc,char **argv){
    lyxutils::Vector3<int> a{1,2,3};
    lyxutils::Vector3<float> b{3,2,1};
    lyxutils::Vector3<double> c(5,2,7);
    lyxutils::Vector3<long> d({4});
    displayVec("a=",a);
    displayVec("b=",b);
    displayVec("c=",c);
    displayVec("d=",d);
    auto e=a+b;
    auto f=a+3.6;
    auto g=4l+a;
//    TD<decltype(e)> tde;
    displayVec("e=a+b=",e);
    displayVec("f=a+3.6=",f);
    displayVec("g=long(4)+a=",g);
    auto h=b-c;
    auto i=b-0.5;
    auto j=double(7)-b;
    displayVec("h=b-c=",h);
    displayVec("i=b-0.5=",i);
    displayVec("j=double(7)-b=",j);
    auto k=a*b;
    auto l=c*2;
    auto m=3*c;
    displayVec("k=a*b=",k);
    auto k1=a.dot(b);
    cout<<"k1=a.dot(b)="<<k1<<",type:"<< typeid(k1).name()<<endl;
    displayVec("l=c*2=",l);
    displayVec("m=3*c=",m);
    auto n=d/2;
    displayVec("n=d/2=",n);
    auto o=b.cross(c);
    displayVec("o=b.cross(c)=",o);
    auto p=2/b;
    displayVec("p=2/b=",p);
    lyxutils::Vector3<double> q(p);
    displayVec("q(with T=double) initiated by p=",q);
    lyxutils::Vector3<float> r;
    displayVec("original r=",r);
    r=c;
    displayVec("assign c to r=",r);
    cout<<"mold of r(rank=2)="<<r.mold()<<endl;
    cout<<"rank range from 0~7,mold=";
    for(int rank:{0,1,2,3,4,5,6,7})cout<<r.mold(rank)<<" ";
    cout<<endl;
    lyxutils::Vector3<unsigned char> s({1,2,3});
    lyxutils::Vector3<int> t({1,2,3});
    lyxutils::Vector3<float> u({1.001,2.001,3.001});
    lyxutils::Vector3<double> v({1.0001,2.0001,3.0001});
    displayVec("s=",s.asType<int>());
    displayVec("t=",t);
    displayVec("u=",u);
    displayVec("v=",v);
    cout<<"s==t?"<<s.equal(t)<<endl;
    cout<<"s==u?"<<s.equal(u)<<",s==u?(precision=0.001)"<<s.equal(u,0.001)<<endl;
    cout<<"t==v?"<<t.equal(v)<<",t==v?(precision=0.0001)"<<t.equal(v,0.0001)<<",t==v?(precision=0.00011)"<<t.equal(v,0.00011)<<endl;
    cout<<"u==v?"<<u.equal(v)<<",u==v?(precision=0.0001)"<<u.equal(v,0.0001)<<endl;
    cout<<"u==Vector3f({1,2,3})?"<<u.equal(lyxutils::Vector3<float>({1,2,3}))<<endl;
    vector<float> w={7,8,9,10,11};
    cout<<"vector:";
    for(int num:w)cout<<num<<",";
    cout<<endl;
    lyxutils::Vector3<float> x(w);
    cout<<"vector to Vector3:("<<x<<")"<<endl;
    cout<<"back to vector:";
    vector<float> y=x.toStdVector();
    for(int num:y)cout<<num<<",";
    cout<<endl;
    lyxutils::Vector3<float> z(w,3);
    cout<<"vector to Vector3(from index 3):("<<z<<")"<<endl;
    vector<string> aa={"1","2","3","4","5"};
    cout<<"test convert vector of string to Vector3f and Vector3i:"<<endl;
    cout<<"vector of strings:";
    for(string s:aa)cout<<s<<" ";
    cout<<endl;
    lyxutils::Vector3<int> bb;
    bb.fromStringVector(aa);
    lyxutils::Vector3<float> cc;
    cc.fromStringVector(aa, 3);
    displayVec("first 3 elements as int:",bb);
    displayVec("4th to 6th elements as float:",cc);
    Vec3u g_c=lyxutils::colors::green;
    Vec3i tri_idx={3,2,1};
    Vec3f f_vec={2.3,3.1,1.7};
    Vec3d d_vec={1.118,8,229,9.336};
    displayVec("green color(displayed as int vector):",g_c.asType<int>());
    displayVec("triple index:",tri_idx);
    displayVec("float vector:",f_vec);
    displayVec("dounble vector:",d_vec);
}